//===================================================================
// Date        : 2023-03-27
// Description : 
//
// Common Flip-Flops defines.
// 
// Summary of FF defines:
//   - WDFFR     : asynchronous reset
//   - WDFFER    : asynchronous reset and enable control
//   - WDFFENR   : enable control, without reset
//   - WDFFNR    : without reset
//   - WDFFRVAL  : asynchronous reset and reset value
//   - WDFFERVAL : asynchronous reset, reset value and enable control
//   - WNDFFER   : negedge clock, asynchronous reset and enable control
// 
// Instantiation:
//   WDFFR(signal_q, signal_d, clk, rst_n)
//   WDFFER(signal_q, signal_d, signal_en, clk, rst_n)
//   WDFFENR(signal_q, signal_d, signal_en, clk)
//   WDFFNR(signal_q, signal_d, clk)
//   WDFFRVAL(signal_q, signal_d, clk, rst_n, rstval)
//   WDFFERVAL(signal_q, signal_d, signal_en, clk, rst_n, rstval)
//   WNDFFER(signal_q, signal_d, signal_en, clk, rst_n)
//
//===================================================================

`ifndef __WING_CBB_DEFINE_DFF__
`define __WING_CBB_DEFINE_DFF__

//------------------------------------------------------------
// Flip-Flop with asynchronous reset
//  - reset value = '0
//  - NO enable control
//------------------------------------------------------------
`define WDFFR(__q, __d, __clk, __rst_n)               \
  always_ff @(posedge __clk or negedge __rst_n) begin \
    if (!__rst_n) begin                               \
        __q <= '0;                                    \
    end else begin                                    \
        __q <= __d;                                   \
    end                                               \
  end

//------------------------------------------------------------
// Flip-Flop with asynchronous reset and enable control
//  - reset value = '0
//  - HAS enable control
//------------------------------------------------------------
`define WDFFER(__q, __d, __en, __clk, __rst_n)        \
  always_ff @(posedge __clk or negedge __rst_n) begin \
    if (!__rst_n) begin                               \
        __q <= '0;                                    \
    end else if (__en) begin                          \
        __q <= __d;                                   \
    end                                               \
  end

//------------------------------------------------------------
// Flip-Flop with enable control, without reset
//  - NO reset
//  - HAS enable control
//------------------------------------------------------------
`define WDFFENR(__q, __d, __en, __clk)  \
  always_ff @(posedge __clk) begin      \
    if (__en) __q <= __d;               \
  end

//------------------------------------------------------------
// Flip-Flop without reset
//  - NO reset
//  - NO enable control
//------------------------------------------------------------
`define WDFFNR(__q, __d, __clk)    \
  always_ff @(posedge __clk) begin \
        __q <= __d;                \
  end

//------------------------------------------------------------
// Flip-Flop with asynchronous reset and reset value
//  - reset value is configurable
//  - NO enable control
//------------------------------------------------------------
`define WDFFRVAL(__q, __d, __clk, __rst_n, __rstval)  \
  always_ff @(posedge __clk or negedge __rst_n) begin \
    if (!__rst_n) begin                               \
        __q <= __rstval;                              \
    end else begin                                    \
        __q <= __d;                                   \
    end                                               \
  end

//------------------------------------------------------------
// Flip-Flop with asynchronous reset, reset value and enable
//  - reset value is configurable
//  - HAS enable control
//------------------------------------------------------------
`define WDFFERVAL(__q, __d, __en, __clk, __rst_n, __rstval) \
  always_ff @(posedge __clk or negedge __rst_n) begin       \
    if (!__rst_n) begin                                     \
        __q <= __rstval;                                    \
    end else if (__en) begin                                \
        __q <= __d;                                         \
    end                                                     \
  end

//------------------------------------------------------------
// Flip-Flop with asynchronous reset and enable control
//  - Negedge clock edge
//  - reset value = '0
//  - HAS enable control
//------------------------------------------------------------
`define WNDFFER(__q, __d, __en, __clk, __rst_n)       \
  always_ff @(negedge __clk or negedge __rst_n) begin \
    if (!__rst_n) begin                               \
        __q <= '0;                                    \
    end else if (__en) begin                          \
        __q <= __d;                                   \
    end                                               \
  end

//------------------------------------------------------------
// Flip-Flop with asynchronous reset and enable control
//  - Negedge clock edge
//  - reset value = '0
//  - HAS enable control
//------------------------------------------------------------
`define WNDFFR(__q, __d,__clk, __rst_n)       \
  always_ff @(negedge __clk or negedge __rst_n) begin \
    if (!__rst_n) begin                               \
      __q <= '0;                                      \
    end else begin                                    \
      __q <= __d;                                     \
    end                                               \
  end
  
`endif